package com.zmn.mcc.business.impl.dpermit.product;

import com.zmn.base.product.common.consts.BaseProductConsts;
import com.zmn.base.product.common.dto.product.erp.ProductGroupDRO;
import com.zmn.base.product.dubbo.interfaces.product.foreign.ProductGroupForeignListRemoteService;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.mcc.business.interfaces.dpermit.product.DpermitProductGroupBService;
import com.zmn.mcc.manager.utils.DpermitUtil;
import com.zmn.mcc.model.dto.dpermit.DpermitBaseDO;
import com.zmn.mcc.model.dto.dpermit.DpermitSimpleDO;
import org.apache.commons.collections.CollectionUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author tanbiao
 * @description
 * @modifier
 * @since 2020/10/29 16:18
 **/
@Service
public class DpermitProductGroupBServiceImpl implements DpermitProductGroupBService {

    private final static Integer TOP_LEVEL = 0;

    @DubboReference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION, check = false)
    private ProductGroupForeignListRemoteService productGroupListRemoteService;

    @Override
    public List<DpermitSimpleDO> listProductGroupAndDpermitChecked(Integer status, List<? extends DpermitBaseDO> dpermits) {
        List<String> dpermitIds = null;
        if (CollectionUtil.isNullOrEmpty(dpermits)) {
            dpermitIds = new ArrayList<>(1);
        } else {
            dpermitIds = dpermits.stream().map(e -> e.getDataId() + "_" + e.getDataLevel()).collect(Collectors.toList());
        }
        // ID和二级业务线对象的映射关系
        Map<String, DpermitSimpleDO> map = new HashMap<>();

        // 查询出所有的产品数据权限
        ResponseDTO<List<ProductGroupDRO>> responseDTO = productGroupListRemoteService.listTreeByStatus(status);
        List<ProductGroupDRO> groupVOS = new ArrayList<>();
        if (responseDTO.isSuccess()) {
            groupVOS.addAll(responseDTO.getData());
        }

        //将查询的数据进行分级处理，业务类型为一级只有三个，业务线为二级，产品分组为三级
        List<DpermitSimpleDO> items = createTopDpermitSimpleDO(dpermitIds);
        for (ProductGroupDRO groupVO : groupVOS) {

            // 二级业务线对象
            DpermitSimpleDO simple = this.parseToLevelTwoDpermitSimpleDO(groupVO);
            if (Objects.isNull(simple)) {
                continue;
            }

            //三级产品组对象
            DpermitSimpleDO simpleSub = this.parseToLevelThrDpermitSimpleDO(groupVO);

            // 加入映射关系map
            if (Objects.isNull(map.get(simple.getDataId() + "_" + simple.getLevel()))) {
                map.put(simple.getDataId() + "_" + simple.getLevel(), simple);
                items.add(simple);
            }

            // 选中已分配
            if (dpermitIds.contains(simple.getDataId() + "_" + simple.getLevel())) {
                simple.setChecked(true);
            }

            // 三级挂载到二级，同时选中已分配
            addSubs(simpleSub, map, dpermitIds);

        }

        return items;
    }


    @Override
    public List<DpermitSimpleDO> listProductGroupTreeAndDpermitChecked(Integer status, List<String> dpermitIds) {
        if (CollectionUtils.isEmpty(dpermitIds)) {
            return Collections.EMPTY_LIST;
        }
        // ID和二级业务线对象的映射关系
        Map<String, DpermitSimpleDO> map = new HashMap<>();

        // 查询出所有的产品数据权限
        // ProductGroupQuery query = new ProductGroupQuery();
        // query.setStatus(status);
        // List<ProductGroupVO> groupVOS = productGroupService.listTreeByQuery(query);
        ResponseDTO<List<ProductGroupDRO>> responseDTO = productGroupListRemoteService.listTreeByStatus(status);
        List<ProductGroupDRO> groupVOS = new ArrayList<>();
        if (responseDTO.isSuccess()) {
            groupVOS.addAll(responseDTO.getData());
        }

        //将查询的数据进行分级处理，业务类型为一级只有三个，业务线为二级，产品分组为三级
        List<DpermitSimpleDO> items = createTopDpermitSimpleDO(dpermitIds);
        for (ProductGroupDRO groupVO : groupVOS) {

            // 二级业务线对象
            DpermitSimpleDO simple = this.parseToLevelTwoDpermitSimpleDO(groupVO);
            if (Objects.isNull(simple)) {
                continue;
            }

            //三级产品组对象
            DpermitSimpleDO simpleSub = this.parseToLevelThrDpermitSimpleDO(groupVO);

            // 加入映射关系map
            if (Objects.isNull(map.get(simple.getDataId() + "_" + simple.getLevel()))) {
                map.put(simple.getDataId() + "_" + simple.getLevel(), simple);
                items.get(simple.getParentId() - 1).getSubors().add(simple);
            }

            // 选中已分配
            if (dpermitIds.contains(simple.getDataId() + "_" + simple.getLevel())) {
                simple.setChecked(true);
            }

            // 三级挂载到二级，同时选中已分配
            addSubs(simpleSub, map, dpermitIds);
        }

        /**
         * 检查并处理简单数据对象选中状态
         * 下级部分选中则上级选中，下级全部选中则对上级标识
         */
        DpermitUtil.checkSelected(items, false);
        return items;
    }

    private DpermitSimpleDO parseToLevelTwoDpermitSimpleDO(ProductGroupDRO groupVO) {
        if (!NumberUtil.isPositiveInteger(groupVO.getBizLine())) {
            return null;
        }
        DpermitSimpleDO cDepermitDO = new DpermitSimpleDO();
        cDepermitDO.setDataId(groupVO.getBizLine());
        cDepermitDO.setDataName(groupVO.getBizLineName());
        cDepermitDO.setParentId(groupVO.getBizType());
        cDepermitDO.setStatus(GlobalConsts.YES);
        cDepermitDO.setLevel(GlobalConsts.LEVEL_2);
        return cDepermitDO;
    }

    private DpermitSimpleDO parseToLevelThrDpermitSimpleDO(ProductGroupDRO groupVO) {
        if (!NumberUtil.isPositiveInteger(groupVO.getGroupId())) {
            return null;
        }
        DpermitSimpleDO cDepermitDO = new DpermitSimpleDO();
        cDepermitDO.setDataId(groupVO.getGroupId());
        cDepermitDO.setDataName(groupVO.getName());
        cDepermitDO.setParentId(groupVO.getBizLine());
        cDepermitDO.setStatus(GlobalConsts.YES);
        cDepermitDO.setLevel(GlobalConsts.LEVEL_3);
        return cDepermitDO;
    }

    private void addSubs(DpermitSimpleDO simpleSub, Map<String, DpermitSimpleDO> map, List<String> dpermitIds) {
        if (simpleSub != null) {
            DpermitSimpleDO parent = map.get(simpleSub.getParentId() + "_" + (simpleSub.getLevel() - 1));
            if (parent != null) {
                if (dpermitIds.contains(simpleSub.getDataId() + "_" + simpleSub.getLevel())) {
                    simpleSub.setChecked(true);
                }
                parent.getSubors().add(simpleSub);
            }
        }
    }


    /**
     * 一级结构为业务类型只有三个固定
     *
     * @return
     */
    private List<DpermitSimpleDO> createTopDpermitSimpleDO(List<String> dpermitIds) {
        List<DpermitSimpleDO> topList = new ArrayList<>();

        //c-保外
        DpermitSimpleDO cDepermitDO = new DpermitSimpleDO();
        cDepermitDO.setDataId(BaseProductConsts.BIZ_TYPE_C);
        cDepermitDO.setDataName(BaseProductConsts.BIZ_TYPE_C_EN_CN);
        cDepermitDO.setParentId(TOP_LEVEL);
        cDepermitDO.setStatus(GlobalConsts.YES);
        cDepermitDO.setLevel(GlobalConsts.LEVEL_1);
        cDepermitDO.setChecked(dpermitIds.contains(cDepermitDO.getDataId() + "_" + GlobalConsts.LEVEL_1));

        //f-保内
        DpermitSimpleDO fDepermitDO = new DpermitSimpleDO();
        fDepermitDO.setDataId(BaseProductConsts.BIZ_TYPE_F);
        fDepermitDO.setDataName(BaseProductConsts.BIZ_TYPE_F_EN_CN);
        fDepermitDO.setParentId(TOP_LEVEL);
        fDepermitDO.setStatus(GlobalConsts.YES);
        fDepermitDO.setLevel(GlobalConsts.LEVEL_1);
        fDepermitDO.setChecked(dpermitIds.contains(fDepermitDO.getDataId() + "_" + GlobalConsts.LEVEL_1));

        //B-工程业务
        DpermitSimpleDO bDepermitDO = new DpermitSimpleDO();
        bDepermitDO.setDataId(BaseProductConsts.BIZ_TYPE_B);
        bDepermitDO.setDataName(BaseProductConsts.BIZ_TYPE_B_EN_CN);
        bDepermitDO.setParentId(TOP_LEVEL);
        bDepermitDO.setStatus(GlobalConsts.YES);
        bDepermitDO.setLevel(GlobalConsts.LEVEL_1);
        bDepermitDO.setChecked(dpermitIds.contains(bDepermitDO.getDataId() + "_" + GlobalConsts.LEVEL_1));

        topList.add(cDepermitDO);
        topList.add(fDepermitDO);
        topList.add(bDepermitDO);
        return topList;

    }
}
